// Package logger 提供结构化日志记录功能
// 支持不同日志级别和格式，包含请求ID追踪等功能
package logger

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"time"
)

// 彩色ANSI码
const (
	colorReset  = "\033[0m"
	colorRed    = "\033[31m"
	colorYellow = "\033[33m"
	colorBlue   = "\033[34m"
	colorCyan   = "\033[36m"
	colorWhite  = "\033[37m"
	colorGreen  = "\033[32m"
)

// LogLevel 日志级别类型
type LogLevel int

const (
	DEBUG LogLevel = iota
	INFO
	WARN
	ERROR
	FATAL
)

// String 返回日志级别的字符串表示
func (l LogLevel) String() string {
	switch l {
	case DEBUG:
		return "DEBUG"
	case INFO:
		return "INFO"
	case WARN:
		return "WARN"
	case ERROR:
		return "ERROR"
	case FATAL:
		return "FATAL"
	default:
		return "UNKNOWN"
	}
}

// Logger 日志记录器结构体
type Logger struct {
	level  LogLevel // 当前日志级别
	format string   // 日志格式 (json/text)
	logger *log.Logger
}

// LogEntry 日志条目结构体
// 用于结构化日志记录
type LogEntry struct {
	Timestamp time.Time              `json:"timestamp"`            // 时间戳
	Level     string                 `json:"level"`                // 日志级别
	Message   string                 `json:"message"`              // 日志消息
	RequestID string                 `json:"request_id,omitempty"` // 请求ID
	Data      map[string]interface{} `json:"data,omitempty"`       // 附加数据
}

// New 创建新的日志记录器
// level: 日志级别字符串 (debug/info/warn/error/fatal)
// format: 日志格式 (json/text)
func New(level, format string) *Logger {
	logLevel := parseLogLevel(level)
	return &Logger{
		level:  logLevel,
		format: format,
		logger: log.New(os.Stdout, "", 0),
	}
}

// parseLogLevel 解析日志级别字符串
func parseLogLevel(level string) LogLevel {
	switch level {
	case "debug":
		return DEBUG
	case "info":
		return INFO
	case "warn":
		return WARN
	case "error":
		return ERROR
	case "fatal":
		return FATAL
	default:
		return INFO
	}
}

// Debug 记录调试级别日志
func (l *Logger) Debug(message string, requestID string, data map[string]interface{}) {
	l.log(DEBUG, message, requestID, data)
}

// Info 记录信息级别日志
func (l *Logger) Info(message string, requestID string, data map[string]interface{}) {
	l.log(INFO, message, requestID, data)
}

// Warn 记录警告级别日志
func (l *Logger) Warn(message string, requestID string, data map[string]interface{}) {
	l.log(WARN, message, requestID, data)
}

// Error 记录错误级别日志
func (l *Logger) Error(message string, requestID string, data map[string]interface{}) {
	l.log(ERROR, message, requestID, data)
}

// Fatal 记录致命错误级别日志并退出程序
func (l *Logger) Fatal(message string, requestID string, data map[string]interface{}) {
	l.log(FATAL, message, requestID, data)
	os.Exit(1)
}

// log 内部日志记录方法
// 根据配置的格式输出结构化或文本格式的日志
func (l *Logger) log(level LogLevel, message, requestID string, data map[string]interface{}) {
	// 检查日志级别是否满足输出条件
	if level < l.level {
		return
	}

	entry := LogEntry{
		Timestamp: time.Now(),
		Level:     level.String(),
		Message:   message,
		RequestID: requestID,
		Data:      data,
	}

	var output string
	if l.format == "json" {
		// JSON格式输出
		if jsonBytes, err := json.Marshal(entry); err == nil {
			output = string(jsonBytes)
		} else {
			output = fmt.Sprintf("Failed to marshal log entry: %v", err)
		}
	} else {
		// 文本格式输出
		output = l.formatTextLog(entry)
	}

	l.logger.Println(output)
}

// formatTextLog 格式化文本日志，带颜色
func (l *Logger) formatTextLog(entry LogEntry) string {
	timestamp := entry.Timestamp.Format("2006-01-02 15:04:05")
	levelColor := colorWhite
	switch entry.Level {
	case "INFO":
		levelColor = colorGreen
	case "WARN":
		levelColor = colorYellow
	case "ERROR":
		levelColor = colorRed
	case "FATAL":
		levelColor = colorRed
	case "DEBUG":
		levelColor = colorCyan
	}
	text := fmt.Sprintf("[%s] %s[%s]%s : %s", timestamp, levelColor, entry.Level, colorReset, entry.Message)
	if entry.RequestID != "" {
		text += fmt.Sprintf(" [RequestID: %s]", entry.RequestID)
	}
	if len(entry.Data) > 0 {
		if dataBytes, err := json.Marshal(entry.Data); err == nil {
			text += fmt.Sprintf(" Data: %s", string(dataBytes))
		}
	}
	return text
}

// WithRequestID 创建带有请求ID的日志方法集合
// 返回一个包含预设请求ID的日志记录函数集合
func (l *Logger) WithRequestID(requestID string) *RequestLogger {
	return &RequestLogger{
		logger:    l,
		requestID: requestID,
	}
}

// RequestLogger 带请求ID的日志记录器
type RequestLogger struct {
	logger    *Logger
	requestID string
}

// Debug 记录调试级别日志（带请求ID）
func (rl *RequestLogger) Debug(message string, data map[string]interface{}) {
	rl.logger.Debug(message, rl.requestID, data)
}

// Info 记录信息级别日志（带请求ID）
func (rl *RequestLogger) Info(message string, data map[string]interface{}) {
	rl.logger.Info(message, rl.requestID, data)
}

// Warn 记录警告级别日志（带请求ID）
func (rl *RequestLogger) Warn(message string, data map[string]interface{}) {
	rl.logger.Warn(message, rl.requestID, data)
}

// Error 记录错误级别日志（带请求ID）
func (rl *RequestLogger) Error(message string, data map[string]interface{}) {
	rl.logger.Error(message, rl.requestID, data)
}

// Fatal 记录致命错误级别日志（带请求ID）并退出程序
func (rl *RequestLogger) Fatal(message string, data map[string]interface{}) {
	rl.logger.Fatal(message, rl.requestID, data)
}
